package com.yilin.platform.base_core.commons.encrypt;


import com.yilin.platform.base_core.commons.utils.StringUtil;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.ByteArrayOutputStream;
import java.nio.charset.StandardCharsets;

/*
 * by lil AES加密
 * */
public class AESUtil {

	public static final String AES_CBS = "AES/CBC/PKCS5Padding";
	public static final String AES_KEY = "AES";
	private static final String KEY = "7e493d6153887a0a7e493d6153887a0a";
	private static final byte[] KEYIV = { 1, 9, 9, 0, 0, 5, 1, 7, 8, 3, 7, 1, 0, 8, 4, 8 };

	public static byte[] encryptAesCBC(byte[] data, byte[] key, byte[] iv) {
		return encryptAesCBC(data, key, iv, Cipher.ENCRYPT_MODE);
	}

	public static byte[] decryptAesCBC(byte[] data, byte[] key, byte[] iv) {
		return encryptAesCBC(data, key, iv, Cipher.DECRYPT_MODE);
	}

	private static byte[] encryptAesCBC(byte[] data, byte[] key, byte[] iv, int encriptMode) {
		byte[] ret = null;
		try {
			if (key == null) {
				key = ByteArrayUtil.hex2byte(KEY);
			}
			if (iv == null) {
				iv = KEYIV;
			}
			Cipher cipher = Cipher.getInstance(AES_CBS);
			SecretKeySpec keySpec = new SecretKeySpec(key, AES_KEY);
			IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
			cipher.init(encriptMode, keySpec, ivParameterSpec);
			int cnt = (data.length + 15) / 16 * 16;
			ByteArrayOutputStream stream = new ByteArrayOutputStream(cnt);
			stream.write(cipher.doFinal(data));
			ret = stream.toByteArray();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return ret;
	}

	// 16字节 默认Key
	private static String default_aesKey = "66a5d79394b647c18f7d4eba4a56e737";
	// 16字节 默认加密向量
	private static String default_aesIv = "feb6f989750e98569953a9a8b9165597";



	/**
	 * AES加密
	 */
	public static String encrypt(String data, String aesKey) {
		if (StringUtil.isEmpty(data)) return data;
		if (StringUtil.isEmpty(aesKey)) aesKey = default_aesKey;
		aesKey = makeUpFor0By32( aesKey);
		String aesIv = default_aesIv;
		byte[] tokenBytes = ByteArrayUtil.hex2byte(aesKey);
		byte[] aesIvBytes = ByteArrayUtil.hex2byte(aesIv);
		byte[] dataBytes = data.getBytes(StandardCharsets.UTF_8);
		byte[] byteData = encryptAesCBC(dataBytes, tokenBytes, aesIvBytes);
		return Base64Util.base64Encode(byteData).replaceAll("\r\n","");
	}

	/**
	 * AES解密
	 */
	public static String decrypt(String data, String aesKey) {
		if (StringUtil.isEmpty(data)) return null;
		if (StringUtil.isEmpty(aesKey)) aesKey = default_aesKey;
		aesKey = makeUpFor0By32( aesKey);
		String aesIv = default_aesIv;
		byte[] tokenBytes = ByteArrayUtil.hex2byte(aesKey);
		byte[] aesIvBytes = ByteArrayUtil.hex2byte(aesIv);
		byte[] dataBytes = Base64Util.base64Decode(data);
		byte[] byteData = decryptAesCBC(dataBytes, tokenBytes, aesIvBytes);
		if (byteData == null) return data;
		return new String(byteData, StandardCharsets.UTF_8);
	}

	// 位数超过32位，截取，小于32位，补0
	public static String makeUpFor0By32(String aesKey){
		if (aesKey==null) return null;
		if (aesKey.length()>32) aesKey = aesKey.substring(0, 32);
		if (aesKey.length()<32){
			int l = 32-aesKey.length();
			StringBuilder aesKeyBuilder = new StringBuilder(aesKey);
			for (int i = 0; i<l; i++) aesKeyBuilder.append("0");
			aesKey = aesKeyBuilder.toString();
		}
		return aesKey;
	}

	//4kasfQQo+ugBfAGWNg9/0IW8miKz5gEaQyWWyyGz0J8=
	public static void main(String[] args) {
		System.out.println(encrypt("25jjhgg",Md5Util.md5("4kasfQQo+ugBfAGWNg9/0IW8miKz5gEaQyWWyyGz0J8=")));
	}
}
